package com.elasticsearch.elasticsearch;

import org.elasticsearch.index.query.QueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.bucket.terms.StringTerms;
import org.elasticsearch.search.aggregations.metrics.avg.InternalAvg;
import org.elasticsearch.search.aggregations.metrics.valuecount.InternalValueCount;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.elasticsearch.core.ElasticsearchTemplate;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.query.FetchSourceFilter;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class NoticeController {
	@Autowired
	private NoticeRepository nticeRepository;

	@Autowired
	private ElasticsearchTemplate elasticsearchTemplate;


	@GetMapping("/save")
	public Object save(@RequestParam long id,@RequestParam String title){
		Notice article = new Notice();
		article.setId(id);
		article.setReadCount(2);
		article.setTitle(title);
		article.setExchangeMc("MC");
		return nticeRepository.save(article);
	}

	@GetMapping("/{id}")
	public Object findid(@PathVariable  long id) throws Exception {
		//elasticsearchTemplate.str
		return nticeRepository.findById(id).get();
	}

	@GetMapping("/delete/{id}")
	public  void deleteIndex(@PathVariable Long id){
		nticeRepository.deleteById(id);
	}
	@GetMapping("/savelist")
	public Object saveList(){
		List<Notice> notices=new ArrayList<>();

		Notice article = new Notice();
		article.setId(4L);
		article.setReadCount(1);
		article.setTitle("批量测试1");
		article.setExchangeMc("Mc1");


		Notice article1 = new Notice();
		article1.setId(5L);
		article1.setReadCount(3);
		article1.setTitle("批量测试1");
		article1.setExchangeMc("Mc2");
		notices.add(article);
		notices.add(article1);
		return nticeRepository.saveAll(notices);
	}

	@GetMapping("/findall")
	public Object  findAll(){
		return nticeRepository.findAll(Sort.by("id").ascending());
	}

	@GetMapping("/matchQuery")
	public  Object matchQuery(){
		NativeSearchQueryBuilder queryBuilder = new NativeSearchQueryBuilder();
		queryBuilder.withQuery(QueryBuilders.matchQuery("title","测试"));
		//添加排序
		queryBuilder.withSort(SortBuilders.fieldSort("id").order(SortOrder.ASC));

		//返回的为分页对象
		return nticeRepository.search(queryBuilder.build());
	}



	@GetMapping("/agg")
	public Object agg(){
		NativeSearchQueryBuilder queryBuilder=new NativeSearchQueryBuilder();
		queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));

		queryBuilder.addAggregation(
				//按照readCount字段分组
				//AggregationBuilders.terms("brands").field("readCount")
				//统计readCount某个字段的数量
				AggregationBuilders.count("brands").field("readCount")
		);

		AggregatedPage<Notice> aggPage = (AggregatedPage<Notice>) nticeRepository.search(queryBuilder.build());
		//StringTerms agg = (StringTerms) aggPage.getAggregation("brands");

		//List<StringTerms.Bucket> buckets = agg.getBuckets();

		// 3.3、遍历
	/*	for (StringTerms.Bucket bucket : buckets) {
			// 3.4、获取桶中的key，即品牌名称
			System.out.println(bucket.getKeyAsString());
			// 3.5、获取桶中的文档数量
			System.out.println(bucket.getDocCount());
		}*/
		InternalValueCount agg= (InternalValueCount) aggPage.getAggregation("brands");
		System.out.println(agg.getValue());

		return null;
	}
	/*
	*
	* 	（1）统计某个字段的数量
	 	 ValueCountBuilder vcb=  AggregationBuilders.count("count_uid").field("uid");
		（2）去重统计某个字段的数量（有少量误差）
		 CardinalityBuilder cb= AggregationBuilders.cardinality("distinct_count_uid").field("uid");
		（3）聚合过滤
		FilterAggregationBuilder fab= AggregationBuilders.filter("uid_filter").filter(QueryBuilders.queryStringQuery("uid:001"));
		（4）按某个字段分组
		TermsBuilder tb=  AggregationBuilders.terms("group_name").field("name");
		（5）求和
		SumBuilder  sumBuilder=	AggregationBuilders.sum("sum_price").field("price");
		（6）求平均
		AvgBuilder ab= AggregationBuilders.avg("avg_price").field("price");
		（7）求最大值
		MaxBuilder mb= AggregationBuilders.max("max_price").field("price");
		（8）求最小值
		MinBuilder min=	AggregationBuilders.min("min_price").field("price");
		（9）按日期间隔分组
		DateHistogramBuilder dhb= AggregationBuilders.dateHistogram("dh").field("date");
		（10）获取聚合里面的结果
		TopHitsBuilder thb=  AggregationBuilders.topHits("top_result");
		（11）嵌套的聚合
		NestedBuilder nb= AggregationBuilders.nested("negsted_path").path("quests");
		（12）反转嵌套
		AggregationBuilders.reverseNested("res_negsted").path("kps ");
	* */

	//切记注意实体类型的定义，翻车了好几次，Text类型不支持聚合查询，数字存储对应的数字类型，存储为keyWord也无法经行聚合查询
	@GetMapping("/sumagg")
	public void  subAgg(){
		NativeSearchQueryBuilder queryBuilder=new NativeSearchQueryBuilder();

		queryBuilder.withSourceFilter(new FetchSourceFilter(new String[]{""}, null));

		queryBuilder.addAggregation(
				AggregationBuilders.terms("exchangeMcGroup").field("exchangeMc").subAggregation(
						AggregationBuilders.avg("readCountAvg")	.field("readCount")
				)


		);
		AggregatedPage<Notice> aggPage = (AggregatedPage<Notice>) nticeRepository.search(queryBuilder.build());

		StringTerms agg = (StringTerms) aggPage.getAggregation("exchangeMcGroup");
		// 3.2、获取桶
		List<StringTerms.Bucket> buckets = agg.getBuckets();
		// 3.3、遍历
		for (StringTerms.Bucket bucket : buckets) {
			// 3.4、获取桶中的key，即品牌名称  3.5、获取桶中的文档数量
			System.out.println(bucket.getKeyAsString() + "，共" + bucket.getDocCount() + "标签");

			// 3.6.获取子聚合结果：
			InternalAvg avg = (InternalAvg) bucket.getAggregations().asMap().get("readCountAvg");
			System.out.println("平均阅读量：" + avg.getValue());
		}


	}


}
